#!/usr/bin/env python
# -*- coding: utf-8 -*-
from cta.impl.action.add_account.quant2.add_quant2_account_action import AddQuant2AccountAction
from cta.impl.action.calculate_data.optimize2.calculate_optimize2_bias_data_action import \
    CalculateOptimize2BiasDataAction
from cta.impl.action.calculate_data.optimize2.calculate_optimize2_ma_data_action import CalculateOptimize2MaDataAction
from cta.impl.action.calculate_data.quant2.calculate_quant2_bias_data_action import CalculateQuant2BiasDataAction
from cta.impl.action.calculate_data.quant2.calculate_quant2_ma_data_action import CalculateQuant2MaDataAction
from cta.impl.action.close_position.optimize2.optimize2_close_not_main_contract_action import \
    Optimize2CloseNotMainContractAction
from cta.impl.action.close_position.optimize2.optimize2_fluctuation_pattern_stop_loss_close_position_action import \
    Optimize2FluctuationPatternStopLossClosePositionAction
from cta.impl.action.close_position.quant2.quant2_close_not_main_contract_action import Quant2CloseNotMainContractAction
from cta.impl.action.close_position.quant2.quant2_fluctuation_pattern_stop_loss_close_position_action import Quant2FluctuationPatternStopLossClosePositionAction
from cta.impl.action.close_position.optimize2.optimize2_multi_factor_close_position_action import \
    Optimize2MultiFactorClosePositionAction
from cta.impl.action.log.optimize2.optimize2_log_action import Optimize2LogAction
from cta.impl.action.open_position.optimize2.optimize2_multi_factor_open_position_action import \
    Optimize2MultiFactorOpenPositionAction
from cta.impl.action.open_position.quant2.quant2_multi_factor_open_position_action import Quant2MultiFactorOpenPositionAction
from cta.impl.action.filter.delete_not_main_contract_code_filter_action import DeleteNotMainContractCodeFilterAction
from cta.impl.action.filter.exclude_code_filter_action import ExcludeCodeFilterAction
from cta.impl.action.filter.update_up_down_percentage_within_date_filter_action import \
    UpdateUpDownPercentageWithinDateFilterAction
from cta.impl.action.log.quant2.common_log_action import CommonLogAction
from cta.impl.action.overweight.optimize2.optimize2_multi_factor_overweight_action import \
    Optimize2MultiFactorOverweightAction
from cta.impl.action.prepare_data.common_prepare_data_action import CommonPrepareDataAction
from cta.impl.action.close_position.quant2.quant2_multi_factor_close_position_action import Quant2MultiFactorClosePositionAction
from cta.impl.action.underweight.optimize2.optimize2_multi_factor_underweight_action import \
    Optimize2MultiFactorUnderweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_close_position_action import \
    UpdateOptimize2AccountAfterClosePositionAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_open_position_action import \
    UpdateOptimize2AccountAfterOpenPositionAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_overweight_action import \
    UpdateOptimize2AccountAfterOverweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_underweight_action import \
    UpdateOptimize2AccountAfterUnderweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_before_close_position_action import \
    UpdateOptimize2AccountBeforeClosePositionAction
from cta.impl.action.update_quant2_account.update_quant2_account_after_close_position_action import \
    UpdateQuant2AccountAfterClosePositionAction
from cta.impl.action.update_quant2_account.update_quant2_account_after_open_position_action import \
    UpdateQuant2AccountAfterOpenPosition
from cta.impl.action.update_quant2_account.update_quant2_account_before_close_position_action import \
    UpdateQuant2AccountBeforeClosePositionAction
from cta.impl.step.optimize2.calculate_optimize2_data_step import CalculateOptimize2DataStep
from cta.impl.step.optimize2.optimize2_close_position_step import Optimize2ClosePositionStep
from cta.impl.step.optimize2.optimize2_log_step import Optimize2LogStep
from cta.impl.step.optimize2.optimize2_open_position_step import Optimize2OpenPositionStep
from cta.impl.step.optimize2.optimize2_overweight_step import Optimize2OverweightStep
from cta.impl.step.optimize2.optimize2_underweight_step import Optimize2UnderweightStep
from cta.impl.step.optimize2.update_optimize2_account_after_close_position_step import \
    UpdateOptimize2AccountAfterClosePositionStep
from cta.impl.step.optimize2.update_optimize2_account_after_open_position_step import \
    UpdateOptimize2AccountAfterOpenPositionStep
from cta.impl.step.optimize2.update_optimize2_account_after_overweight_step import \
    UpdateOptimize2AccountAfterOverweightStep
from cta.impl.step.optimize2.update_optimize2_account_after_underweight_step import \
    UpdateOptimize2AccountAfterUnderweightStep
from cta.impl.step.quant2.add_quant2_account_step import AddQuant2AccountStep
from cta.impl.step.quant2.calculate_quant2_data_step import CalculateQuant2DataStep
from cta.impl.step.quant2.quant2_close_position_step import Quant2ClosePositionStep
from cta.impl.step.quant2.common_log_step import CommonLogStep
from cta.impl.step.optimize2.update_optimize2_account_before_close_position_step import \
    UpdateOptimize2AccountBeforeClosePositionStep
from cta.impl.step.update_up_down_percentage_within_date_filter_step import UpdateUpDownPercentageWithinDateFilterStep
from cta.impl.step.quant2.quant2_open_position_step import Quant2OpenPositionStep
from cta.impl.step.prepare_data_step import PrepareDataStep
from cta.impl.step.responsibility_chain_begin_step import ResponsibilityChainBeginStep
from cta.impl.step.responsibility_chain_end_step import ResponsibilityChainEndStep
from cta.impl.step.quant2.update_quant2_account_after_close_position_step import UpdateQuant2AccountAfterClosePositionStep
from cta.impl.step.quant2.update_qunat2_account_before_close_position_step import UpdateQuant2AccountBeforeClosePositionStep
from cta.interface.strategy.abstract_strategy import AbstractStrategy
from web.manager.log_manager import LogManager

Logger = LogManager.get_logger(__name__)

class MultiFactorStrategy(AbstractStrategy):
    """
    量化CTA--截面--多因子：
    1.计算过去一段时间（回溯n天）的收益率，然后降序排列。
    2.int(收益率大于等于0的记录数/记录总数*最大持仓量)，这个就是应当持有的做多的仓位数。最大持仓量-做多的仓位数=做空的仓位数。
    3.比如有45的等待交易的期货，并已经按照收益率降序排列，账号1多仓应该为6，空单应该为4，则取45条记录的前6条和最后4条。其他账号以此类推。
    4.在持仓m个交易日后，再次重复之前的1值至3步。对于每个账号，平仓不应该继续持有的，开仓应该持有的，已经持有的继续持有。
    """

    def __init__(self):
        super().__init__()

        ################################ 定义步骤（职责链设计模式） ################################
        self.responsibility_chain_begin_step = ResponsibilityChainBeginStep()
        # 量化
        self.update_quant2_account_before_close_position_step = UpdateQuant2AccountBeforeClosePositionStep(UpdateQuant2AccountBeforeClosePositionAction())
        self.prepare_data_step = PrepareDataStep(CommonPrepareDataAction())
        self.update_up_down_percentage_with_n_date_filter_step = UpdateUpDownPercentageWithinDateFilterStep(ExcludeCodeFilterAction(), DeleteNotMainContractCodeFilterAction(), UpdateUpDownPercentageWithinDateFilterAction())
        # self.add_quant2_account_step = AddQuant2AccountStep(AddQuant2AccountAction())
        self.quant2_close_position_step = Quant2ClosePositionStep(Quant2CloseNotMainContractAction(), Quant2FluctuationPatternStopLossClosePositionAction(), Quant2MultiFactorClosePositionAction())
        self.update_quant2_account_after_close_position_step = UpdateQuant2AccountAfterClosePositionStep(UpdateQuant2AccountAfterClosePositionAction())
        self.quant2_open_position_step = Quant2OpenPositionStep(Quant2MultiFactorOpenPositionAction())
        self.update_quant2_account_after_open_position_step = UpdateQuant2AccountAfterOpenPosition(UpdateQuant2AccountAfterOpenPosition())
        self.common_log_step = CommonLogStep(CommonLogAction())
        self.calculate_quant2_data_step = CalculateQuant2DataStep(CalculateQuant2MaDataAction(), CalculateQuant2BiasDataAction())
        self.responsibility_chain_end_step = ResponsibilityChainEndStep()
        # 优化
        # self.update_optimize2_account_before_close_position_step = UpdateOptimize2AccountBeforeClosePositionStep(UpdateOptimize2AccountBeforeClosePositionAction())
        # self.optimize2_close_position_step = Optimize2ClosePositionStep(Optimize2CloseNotMainContractAction(), Optimize2FluctuationPatternStopLossClosePositionAction(), Optimize2MultiFactorClosePositionAction())
        # self.update_optimize2_account_after_close_position_step = UpdateOptimize2AccountAfterClosePositionStep(UpdateOptimize2AccountAfterClosePositionAction())
        # self.optimize2_open_position_step = Optimize2OpenPositionStep(Optimize2MultiFactorOpenPositionAction())
        # self.update_optimize2_account_after_open_position_step = UpdateOptimize2AccountAfterOpenPositionStep(UpdateOptimize2AccountAfterOpenPositionAction())
        # self.optimize2_multi_factor_underweight_step = Optimize2UnderweightStep(Optimize2MultiFactorUnderweightAction())
        # self.update_optimize2_account_after_underweight_step = UpdateOptimize2AccountAfterUnderweightStep(UpdateOptimize2AccountAfterUnderweightAction())
        # self.optimize2_multi_factor_overweight_step = Optimize2OverweightStep(Optimize2MultiFactorOverweightAction())
        # self.update_optimize2_account_after_overweight_step = UpdateOptimize2AccountAfterOverweightStep(UpdateOptimize2AccountAfterOverweightAction())
        # self.optimize2_log_step = Optimize2LogStep(Optimize2LogAction())
        # self.calculate_optimize2_data_step = CalculateOptimize2DataStep(CalculateOptimize2MaDataAction(), CalculateOptimize2BiasDataAction())
        # self.responsibility_chain_end_step = ResponsibilityChainEndStep()

        ################################ 定义步骤顺序（职责链设计模式） ################################
        self.responsibility_chain_begin_step.set_successor(self.update_quant2_account_before_close_position_step)
        # 量化
        self.update_quant2_account_before_close_position_step.set_successor(self.prepare_data_step)
        self.prepare_data_step.set_successor(self.update_up_down_percentage_with_n_date_filter_step)
        self.update_up_down_percentage_with_n_date_filter_step.set_successor(self.quant2_close_position_step)
        # self.add_quant2_account_step.set_successor(self.quant2_close_position_step)
        self.quant2_close_position_step.set_successor(self.update_quant2_account_after_close_position_step)
        self.update_quant2_account_after_close_position_step.set_successor(self.quant2_open_position_step)
        self.quant2_open_position_step.set_successor(self.update_quant2_account_after_open_position_step)
        self.update_quant2_account_after_open_position_step.set_successor(self.common_log_step)
        self.common_log_step.set_successor(self.calculate_quant2_data_step)
        self.calculate_quant2_data_step.set_successor(self.responsibility_chain_end_step)
        # self.calculate_quant2_data_step.set_successor(self.update_optimize2_account_before_close_position_step)
        # 优化
        # self.update_optimize2_account_before_close_position_step.set_successor(self.optimize2_close_position_step)
        # self.optimize2_close_position_step.set_successor(self.update_optimize2_account_after_close_position_step)
        # self.update_optimize2_account_after_close_position_step.set_successor(self.optimize2_open_position_step)
        # self.optimize2_open_position_step.set_successor(self.update_optimize2_account_after_open_position_step)
        # self.update_optimize2_account_after_open_position_step.set_successor(self.optimize2_multi_factor_underweight_step)
        # self.optimize2_multi_factor_underweight_step.set_successor(self.update_optimize2_account_after_underweight_step)
        # self.update_optimize2_account_after_underweight_step.set_successor(self.optimize2_multi_factor_overweight_step)
        # self.optimize2_multi_factor_overweight_step.set_successor(self.update_optimize2_account_after_overweight_step)
        # self.update_optimize2_account_after_overweight_step.set_successor(self.optimize2_log_step)
        # self.optimize2_log_step.set_successor(self.calculate_optimize2_data_step)
        # self.calculate_optimize2_data_step.set_successor(self.responsibility_chain_end_step)

    def start(self):
        Logger.info('开始执行：量化CTA--截面--多因子')

        super().exec()
